<script setup lang="ts">
defineOptions({
  name: "Mapshift"
});
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox, ElLoading } from "element-plus";
import axios from "axios";
import EditData from "./type/index";
import { QuestionFilled } from "@element-plus/icons-vue";

const dialogVisible = ref(false);
const formRef = ref(null);
const editFormRef = ref(null);

let loadingInstance = null;

const formData = ref({
  cust: "",
  device: "",
  cpNo: "",
  osBin: "",
  msPos: "",
  msSlide: "",
  msCustomPos: "",
  msCustomBin: "",
  failYield: ""
});

// const API_URL_ADD = "https://localhost:44389/api/mapshift/add";
// const API_URL_QUERY = "https://localhost:44389/api/mapshift/query";
// const API_URL_DEL = "https://localhost:44389/api/mapshift/delete";
// const API_URL_EDIT = "https://localhost:44389/api/mapshift/edit";
// const API_URL_EXPORT = "https://localhost:44389/api/mapshift/export";
const API_URL_ADD = "http://10.20.5.21:8080/api/mapshift/add";
const API_URL_QUERY = "http://10.20.5.21:8080/api/mapshift/query";
const API_URL_DEL = "http://10.20.5.21:8080/api/mapshift/delete";
const API_URL_EDIT = "http://10.20.5.21:8080/api/mapshift/edit";
const API_URL_EXPORT = "http://10.20.5.21:8080/api/mapshift/export";

const rules = {
  cust: [
    { required: true, message: "请输入 Cust", trigger: "blur" },
    {
      max: 3,
      message: "Cust 字段不能超过 3 个字符",
      trigger: "blur"
    },
    {
      pattern: /^[A-Z]+$/,
      message: "Cust 必须为大写字母",
      trigger: "blur"
    }
  ],
  device: [{ required: true, message: "请输入 Device", trigger: "blur" }],
  cpNo: [
    { required: true, message: "请输入 CP No", trigger: "blur" },
    {
      pattern: /^CP.*$/,
      message: "CP No 必须以 'CP' 开头",
      trigger: "blur"
    }
  ],
  osBin: [
    { required: true, message: "请输入 OS Bin", trigger: "blur" },
    {
      pattern: /^(\d+)(\|\d+)*$/, // 确保是以 | 分隔的多个值
      message: "格式错误，多个osBin要用|分隔",
      trigger: "blur"
    }
  ],
  msPos: [
    { required: false, message: "请输入 特征点坐标", trigger: "blur" },
    {
      pattern: /^(-?\d+[Xx]-?\d+)(\|(-?\d+[Xx]-?\d+))*$/,
      message: "格式错误，正确格式示例：1X2|3X4，1代表x坐标，2代表y坐标",
      trigger: "blur"
    }
  ],
  msSlide: [
    { required: false, message: "请输入 特征点坐标", trigger: "blur" },
    {
      pattern: /^(-?\d+[Xx]-?\d+)(\|(-?\d+[Xx]-?\d+))*$/,
      message: "格式错误，正确格式示例：1X2|3X4，1代表x坐标，2代表y坐标",
      trigger: "blur"
    }
  ],
  msCustomPos: [
    { required: false, message: "请输入自定义坐标", trigger: "blur" },
    {
      pattern: /^(-?\d+[Xx]-?\d+)(\|(-?\d+[Xx]-?\d+))*$/,
      message: "格式错误，正确格式示例：1X2|3X4，1代表x坐标，2代表y坐标",
      trigger: "blur"
    }
  ],
  failYield: [
    { required: true, message: "请输入 Fail Yield", trigger: "blur" },
    {
      validator: (rule, value, callback) => {
        const pattern = /^\d+(\.\d+)?$/;
        if (!pattern.test(value)) {
          callback(new Error("只能输入数字"));
        } else {
          callback();
        }
      },
      trigger: "blur"
    }
  ]
};

const openDialog = () => {
  dialogVisible.value = true;
};

const submitForm = () => {
  formRef.value.validate(async valid => {
    if (valid) {
      try {
        const response = await fetch(API_URL_ADD, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(formData.value)
        });

        if (response.ok) {
          ElMessage.success("保存成功");
          dialogVisible.value = false;
          formRef.value.resetFields();
          await fetchData();
        } else {
          ElMessage.error("保存失败！");
        }
      } catch (error) {
        ElMessage.error("请求出错：" + error.message);
      }
    } else {
      ElMessage.error("表单填写不正确");
    }
  });
};

// 数据
const tableData = ref([]);
const searchParams = reactive({ cust: "", device: "" });
const total = ref(50);
const page = ref(1);
const pageSize = ref(10);

const editdialogVisible = ref(false);
const editData = reactive<EditData>({
  cust: "",
  device: "",
  cpNo: "",
  osBin: "",
  msPos: "",
  msSlide: "",
  msCustomPos: "",
  msCustomBin: "",
  failYield: ""
});

const showPreview2 = ref(false);
const srcList2 = ["/tezehngdain.png"];
const showPreview3 = ref(false);
const srcList3 = ["/guangban.png"];

// **获取数据**
const fetchData = async () => {
  try {
    const { data } = await axios.get(API_URL_QUERY, {
      params: {
        ...searchParams,
        page: page.value,
        pageSize: pageSize.value
      }
    });
    tableData.value = data.items;
    total.value = data.total;
  } catch (error) {
    console.error("数据加载失败:", error);
  }
};

// **删除数据**
const deleteRecord = async mms_id => {
  ElMessageBox.confirm("确认删除此记录?", "警告", { type: "warning" })
    .then(async () => {
      await axios.get(`${API_URL_DEL}/${mms_id}`);
      await fetchData();

      ElMessage.success("删除成功");
    })
    .catch(() => {});
};

const resetSearch = () => {
  searchParams.cust = "";
  searchParams.device = "";
  fetchData();
};

const exportData = async () => {
  try {
    loadingInstance = ElLoading.service({
      lock: true,
      text: "正在导出excel，请稍候...",
      background: "rgba(0,0,0,0.3)"
    });

    const response = await axios.get(API_URL_EXPORT, {
      responseType: "blob" // 关键：接收的是文件流
    });

    const blob = new Blob([response.data], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    });

    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = downloadUrl;
    link.download = `MapShift记录表${new Date().toISOString().slice(0, 19).replace(/[-T:]/g, "")}.xlsx`;
    document.body.appendChild(link);
    link.click();
    link.remove();
    window.URL.revokeObjectURL(downloadUrl);
  } catch (error) {
    if (error.response && error.response.data instanceof Blob) {
      const blob = error.response.data;
      const reader = new FileReader();
      reader.onload = () => {
        try {
          // 尝试解析JSON错误信息
          const errorData = JSON.parse(reader.result as string);
          ElMessage.error(errorData.message || "未找到相关记录");
        } catch (e) {
          // 非JSON格式，直接读取文本或默认消息
          ElMessage.error(reader.result.toString() || "请求失败");
        }
      };
      reader.onerror = () => {
        ElMessage.error("解析错误信息失败");
      };
      reader.readAsText(blob);
    } else {
      // 其他错误（如网络问题）
      ElMessage.error(error.message || "请求失败");
    }
  } finally {
    if (loadingInstance) {
      loadingInstance.close();
    }
  }
};

const handlePageChange = newPage => {
  fetchData();
};

// **编辑数据**
const editRecord = row => {
  Object.assign(editData, row);
  editdialogVisible.value = true;
};

const updateRecord = () => {
  editFormRef.value.validate(async valid => {
    if (valid) {
      try {
        await axios.post(`${API_URL_EDIT}`, editData);
        ElMessage.success("更新成功");
        editdialogVisible.value = false;
        fetchData();
      } catch (error) {
        ElMessage.error("更新失败");
      }
    } else {
      ElMessage.error("表单填写不正确");
    }
  });
};

onMounted(() => {
  fetchData();
});
</script>

<template>
  <div>
    <div class="dark:header-container">
      <el-form :inline="true" class="search-form">
        <el-form-item label="Cust">
          <el-input
            v-model="searchParams.cust"
            placeholder="输入 Cust"
            clearable
          />
        </el-form-item>
        <el-form-item label="Device">
          <el-input
            v-model="searchParams.device"
            placeholder="输入 Device"
            clearable
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="fetchData">查询</el-button>
          <el-button @click="resetSearch">重置</el-button>
          <el-button type="primary" @click="openDialog">新增</el-button>
          <el-button @click="exportData">导出</el-button>
        </el-form-item>
      </el-form>
    </div>

    <div style="width: 100%; overflow-x: auto">
      <!-- 数据表格 -->
      <el-table
        :data="tableData"
        border
        style="min-width: 1400px"
        :fit="true"
        class="custom-table"
      >
        <el-table-column label="操作">
          <template #default="{ row }">
            <el-button size="small" @click="editRecord(row)">编辑</el-button>
            <el-button
              size="small"
              type="danger"
              @click="deleteRecord(row.mmsId)"
              >删除</el-button
            >
          </template>
        </el-table-column>
        <el-table-column prop="mmsId" label="MMS ID" width="0" v-if="false" />
        <el-table-column prop="cust" label="Cust" />
        <el-table-column prop="device" label="Device" />
        <el-table-column prop="cpNo" label="CP No" />
        <el-table-column prop="osBin" label="OS Bin" />
        <el-table-column prop="msPos" label="特征点坐标" />
        <el-table-column prop="msSlide" label="光板坐标" />
        <el-table-column prop="msCustomPos" label="自定义坐标" />
        <el-table-column prop="msCustomBin" label="必须是某个bin" />

        <el-table-column prop="failYield" label="Fail Yield" />
      </el-table>
    </div>
    <!-- 分页 -->

    <div class="example-pagination-block">
      <el-pagination
        v-model:current-page="page"
        v-model:page-size="pageSize"
        :total="total"
        layout="prev, pager, next"
        background
        @current-change="handlePageChange"
      />
    </div>

    <el-dialog v-model="dialogVisible" title="新增记录" width="600px">
      <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        label-width="150px"
      >
        <el-form-item label="Cust" prop="cust">
          <el-input v-model="formData.cust" maxlength="10" />
        </el-form-item>
        <el-form-item label="Device" prop="device">
          <el-input v-model="formData.device" maxlength="100" />
        </el-form-item>
        <el-form-item label="CP No" prop="cpNo">
          <el-input v-model="formData.cpNo" maxlength="5" />
        </el-form-item>
        <el-form-item label="OS Bin" prop="osBin">
          <el-input v-model="formData.osBin" maxlength="100" />
        </el-form-item>
        <el-form-item label="特征点坐标" prop="msPos">
          <el-input v-model="formData.msPos" maxlength="255" />
        </el-form-item>
        <el-form-item label="光板坐标" prop="msSlide">
          <el-input v-model="formData.msSlide" maxlength="255" />
        </el-form-item>

        <div
          style="
            margin-bottom: 12px;
            border: 1px dashed #ccc;
            padding: 10px;
            border-radius: 4px;
          "
        >
          <el-form-item label="自定义坐标" prop="msCustomPos">
            <el-input v-model="formData.msCustomPos" maxlength="255" />
          </el-form-item>
          <el-form-item label="必须是某个bin" prop="msCustomBin">
            <el-input v-model="formData.msCustomBin" maxlength="255" />
          </el-form-item>
        </div>

        <el-form-item label="Fail Yield" prop="failYield">
          <el-input v-model="formData.failYield" maxlength="10" />
        </el-form-item>
      </el-form>

      <el-icon><QuestionFilled /></el-icon>
      <div class="form-note">
        <div>
          判定条件1： （左半边边缘的 OS Bin 个数 - 右半边边缘的 OS Bin 个数） ÷
          行数 × 100 ＞ Fail Yield

          <br />
          （上半边边缘的 OS Bin 个数 - 下半边边缘的 OS Bin 个数） ÷ 列数 × 100
          ＞ Fail Yield
        </div>

        <div>判定条件2：对比特征点坐标相同方向是否都出现 OS Bin</div>

        <div @click="showPreview2 = true" style="color: blue; cursor: pointer">
          点击查看案例
        </div>
        <el-image-viewer
          v-if="showPreview2"
          :url-list="srcList2"
          show-progress
          @close="showPreview2 = false"
        />

        <div>判定条件3：判断光板坐标周围一圈是否出现 OS Bin</div>

        <div @click="showPreview3 = true" style="color: blue; cursor: pointer">
          点击查看案例
        </div>
        <el-image-viewer
          v-if="showPreview3"
          :url-list="srcList3"
          show-progress
          @close="showPreview3 = false"
        />

        <div>判定条件4：自定义坐标必须是某个bin</div>
      </div>

      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm">保存</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="editdialogVisible" title="编辑记录">
      <el-form
        ref="editFormRef"
        :model="editData"
        label-width="150px"
        :rules="rules"
      >
        <el-form-item label="Cust" prop="cust">
          <el-input v-model="editData.cust" />
        </el-form-item>
        <el-form-item label="Device" prop="device">
          <el-input v-model="editData.device" />
        </el-form-item>
        <el-form-item label="CP No" prop="cpNo">
          <el-input v-model="editData.cpNo" />
        </el-form-item>
        <el-form-item label="OS Bin" prop="osBin">
          <el-input v-model="editData.osBin" />
        </el-form-item>
        <el-form-item label="特征点坐标" prop="msPos">
          <el-input v-model="editData.msPos" />
        </el-form-item>
        <el-form-item label="光板坐标" prop="msSlide">
          <el-input v-model="editData.msSlide" />
        </el-form-item>

        <div
          style="
            margin-bottom: 12px;
            border: 1px dashed #ccc;
            padding: 10px;
            border-radius: 4px;
          "
        >
          <el-form-item label="自定义坐标" prop="msCustomPos">
            <el-input v-model="editData.msCustomPos" maxlength="255" />
          </el-form-item>
          <el-form-item label="必须是某个bin" prop="msCustomBin">
            <el-input v-model="editData.msCustomBin" maxlength="255" />
          </el-form-item>
        </div>

        <el-form-item label="Fail Yield" prop="failYield">
          <el-input v-model="editData.failYield" />
        </el-form-item>
      </el-form>

      <el-icon><QuestionFilled /></el-icon>
      <div class="form-note">
        <div>
          判定条件1： （左半边边缘的 OS Bin 个数 - 右半边边缘的 OS Bin 个数） ÷
          行数 × 100 ＞ Fail Yield

          <br />
          （上半边边缘的 OS Bin 个数 - 下半边边缘的 OS Bin 个数） ÷ 列数 × 100
          ＞ Fail Yield
        </div>

        <div>判定条件2：对比特征点坐标相同方向是否都出现 OS Bin</div>

        <div @click="showPreview2 = true" style="color: blue; cursor: pointer">
          点击查看案例
        </div>
        <el-image-viewer
          v-if="showPreview2"
          :url-list="srcList2"
          show-progress
          @close="showPreview2 = false"
        />

        <div>判定条件3：判断光板坐标周围一圈是否出现 OS Bin</div>

        <div @click="showPreview3 = true" style="color: blue; cursor: pointer">
          点击查看案例
        </div>
        <el-image-viewer
          v-if="showPreview3"
          :url-list="srcList3"
          show-progress
          @close="showPreview3 = false"
        />

        <div>判定条件4：自定义坐标必须是某个bin</div>
      </div>
      <template #footer>
        <el-button @click="editdialogVisible = false">取消</el-button>
        <el-button type="primary" @click="updateRecord">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
/* 对话框样式优化 */

.form-note {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
  line-height: 1.4;
  margin-left: 20px;
}
.el-dialog {
  max-width: 600px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);

  /* 标题样式 */
  &__header {
    padding: 16px 24px;
    background: #f5f7fa;
    border-bottom: 1px solid #ebeef5;
    margin: 0;

    span {
      font-weight: 600;
      color: #303133;
    }
  }

  /* 内容区域 */
  &__body {
    padding: 20px 24px;
  }

  /* 底部按钮区域 */
  &__footer {
    padding: 16px 24px;
    border-top: 1px solid #ebeef5;
  }
}

/* 头部容器优化 */
.header-container {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 16px;
  background: #fff;
  margin-bottom: 20px;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 搜索表单优化 */
.search-form {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 12px;

  .el-form-item {
    margin-bottom: 0;

    /* 输入框统一宽度 */
    .el-input {
      width: 180px;
      transition: all 0.3s;

      &:hover .el-input__wrapper {
        box-shadow: 0 0 0 1px #409eff inset;
      }
    }

    /* 标签样式 */
    .el-form-item__label {
      color: #606266;
      font-weight: 500;
    }
  }
}

/* 表格优化 */
.el-table {
  margin: 20px 0;
  border-radius: 8px;
  overflow: hidden;

  th.el-table__cell {
    background: #f8f9fa;
    color: #606266;
    font-weight: 600;
  }

  /* 操作按钮间距 */
  .el-button {
    margin-right: 8px;
    &:last-child {
      margin-right: 0;
    }
  }
}

/* 分页优化 */
.example-pagination-block {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;

  .el-pagination {
    padding: 8px 16px;
    background: #fff;
    border-radius: 6px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }
}

/* 表单元素优化 */
.el-form {
  /* 表单项间距 */
  .el-form-item {
    margin-bottom: 18px;

    /* 输入框聚焦效果 */
    .el-input__wrapper {
      transition: all 0.3s;
      &:hover {
        box-shadow: 0 0 0 1px #c0c4cc inset;
      }
      &.is-focus {
        box-shadow: 0 0 0 1px #409eff inset;
      }
    }
  }

  /* 必填项标记 */
  .is-required .el-form-item__label::before {
    color: #f56c6c;
    margin-right: 4px;
  }
}
</style>
